package org.bee.tl.ext;

import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;

import org.bee.tl.core.BeeException;
import org.bee.tl.core.ByteSupportTag;
import org.bee.tl.core.GroupTemplate;
import org.bee.tl.core.Template;
import org.bee.tl.core.io.ByteWriter;

/**
 * 提供一个布局功能，每个页面总是由一定布局，如页面头，菜单，页面脚，以及正文 layout标签允许为正文指定一个布局，如下使用方式
 * <p>
 * 
 * content.html内容如下：
 * 
 * <pre>
 * &lt;%layout(&quot;/org/bee/tl/samples/layout.html&quot;){%&gt;
 *    this is 正文  
 *    ..........
 *    &lt;%}%&gt;
 * </pre>
 * 
 * layout.html 是布局文件，内容如下·
 * 
 * <pre>
 * this is header
 *    this is content:${layoutContent}
 *    this is footer:
 * </pre>
 * <p>
 * 运行content.html模板文件后，，正文文件的内容将被替换到layoutContent的地方，变成如下内容
 * 
 * <pre>
 * this is header
 *    this is content:this is 正文  
 *    ............
 *    this is footer:
 * </pre>
 * 
 * 如果向布局传入参数，则可以使用这种格式
 * <p/>
 * layout(path,{'paraName1':value1,'paraName2',value2})
 * 
 * @author joelli
 * @since 1.1
 * 
 */
public class LayoutTag extends ByteSupportTag {

	ByteWriter tempWriter = null;

	public boolean requriedInput() {
		return true;
	}

	public void makeOutput() {
		if (args.length == 0 || args.length > 2) {
			throw new RuntimeException("参数错误，期望child,map");
		}
		String child = (String) args[0];

		GroupTemplate group = this.template.getGroupTemplate();
		Template t = null;
		try {
			t = group.getFileTemplate(child);
		} catch (IOException e1) {
			throw new RuntimeException(e1);
		}
		if (this.byteContent) {
			t.set("layoutContent", this.inputBytes);
		} else {
			t.set("layoutContent", this.input);
		}

		String key = null;
		for (Entry<String, Object> entry : ctx.getVars().entrySet()) {
			key = entry.getKey();
			if (ctx.getRawList() != null && ctx.getRawList().contains(key)) {
				t.setRawValue(key, entry.getValue());
			} else {
				t.set(entry.getKey(), entry.getValue());
			}

		}

		if (args.length == 2) {
			Map<String, Object> map = (Map<String, Object>) args[1];
			for (Entry<String, Object> entry : map.entrySet()) {
				t.set(entry.getKey(), entry.getValue());
			}
		}

		tempWriter = this.writer.getTempWriter();

		try {
			t.getText(tempWriter);
		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (BeeException e) {
			throw new RuntimeException(e);
		}

	}

	@Override
	public String getOutput() {
		makeOutput();
		return this.tempWriter.getTempString();
	}

	@Override
	public byte[] getOutputAsByte() {
		makeOutput();
		return this.tempWriter.getTempByte();
	}

}
